package com.party.jackclientandroid.controller;

import android.text.TextUtils;

import com.party.jackclientandroid.BaseActivity;
import com.party.jackclientandroid.Constant;
import com.party.jackclientandroid.bean.ImageBean;
import com.party.jackclientandroid.okhttp.OkHttpUtils;
import com.party.jackclientandroid.utils.ConstUtils;
import com.party.jackclientandroid.utils.SDCardFileUtils;
import com.party.jackclientandroid.utils.ToastUtils;

import org.json.JSONObject;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.Callable;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.xiaosai.imagecompress.utils.BitmapUtil;
import okhttp3.Response;

/**
 * 图片上传Controller<br>
 */
public class UploadPictureController extends BaseController {
    private static final String SEPARATOR = ",";
    private static final String COMPRESS_SUCCESS = "1";

    public UploadPictureController(BaseActivity baseActivity) {
        super(baseActivity);
    }

    /**
     * 上次结果监听器
     */
    public interface UploadListener {
        /**
         * 上传图片完成
         *
         * @param result
         */
        void uploadComplete(String result);

        /**
         * 上传图片失败
         *
         * @param result
         */
        void uploadError(String result);
    }

    /**
     * 上传图片
     *
     * @param taskId   任务id
     * @param type     步骤
     * @param urlList  需要上传的图片集合
     * @param listener 上传结果监听器
     */
    public void uploadPicture(long taskId, int type, String imageDomainName, ArrayList<ImageBean> urlList, UploadListener listener) {
        ArrayList<ImageBean> uploadedList = new ArrayList<>();
        ArrayList<ImageBean> uploadList = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        for (ImageBean bean : urlList) {
            if (TextUtils.isEmpty(bean.getImgPath())) continue;
            if (bean.getImgPath().startsWith("http:") || bean.getImgPath().startsWith("https:")) {
                String imgPath = bean.getImgPath();
                // 去掉图片开头的域名
                if (!TextUtils.isEmpty(imageDomainName)) {
                    imgPath = imgPath.replaceAll(imageDomainName, "");
                }
                sb.append(imgPath);
                sb.append(SEPARATOR);
                uploadedList.add(bean);
            } else {
                uploadList.add(bean);
            }
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.lastIndexOf(SEPARATOR));
        }
        if (uploadList.size() == 0) {
            if (listener != null) {
                listener.uploadComplete(sb.toString());
            }
            return;
        }
        uploadNeedPicture(taskId, type, uploadList, sb.toString(), listener);
    }

    /**
     * 上传图片
     *
     * @param taskId      任务id
     * @param type        步骤
     * @param uploadList  需要上传的本地图片集合
     * @param uploadedStr 已经上传过的图片集合字符串
     * @param listener    上传结果监听器
     */
    private void uploadNeedPicture(final long taskId, final int type, final ArrayList<ImageBean> uploadList, final String uploadedStr, final UploadListener listener) {
        String sdCardPath = SDCardFileUtils.getSDCardPath();
        if (TextUtils.isEmpty(sdCardPath)) {
            ToastUtils.t(mApplication, "获取内存卡失败");
            return;
        }
        final String dir2SDCard = ConstUtils.uploadNeedPictureDir();
        Observable.defer(new Callable<ObservableSource<ArrayList<String>>>() {
            @Override
            public ObservableSource<ArrayList<String>> call() throws Exception {
                ArrayList<String> list = new ArrayList<>();
                int size = uploadList.size();
                for (int i = 0; i < size; i++) {
                    ImageBean bean = uploadList.get(i);
                    try {
                        File file = new File(bean.getImgPath());
                        if (!file.exists()) continue;
                        String timeStamp = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss", Locale.ENGLISH).format(new Date());
                        String targetFilePath = dir2SDCard + "/" + timeStamp + "_" + i + "_" + file.getName();
                        String resultStr = BitmapUtil.compressBitmap(bean.getImgPath(), targetFilePath, 500);
                        if (resultStr.equals(COMPRESS_SUCCESS)) {
                            list.add(targetFilePath);
                        }
                    } catch (Exception e) {
                    }
                }
                return Observable.just(list);
            }
        }).subscribeOn(Schedulers.io()).flatMap(new Function<ArrayList<String>, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(ArrayList<String> list) throws Exception {
                StringBuilder sb = new StringBuilder();
                for (String str : list) {
                    File file = new File(str);
                    // 文件不存在
                    if (!file.exists()) continue;
                    Response response = OkHttpUtils
                            .post()
                            .url(Constant.IMAGE_UPLOAD_URL)
                            .addParams("taskId", taskId + "")
                            .addParams("stepId", type + "")
                            .addFile("file", file.getName(), file)
                            .build().execute();
                    String bodyStr = response.body().string();
                    JSONObject jsonObject = new JSONObject(bodyStr);
                    int code = 0;
                    String path = null;
                    if (jsonObject.has("code")) {
                        code = jsonObject.getInt("code");
                    }
                    if (jsonObject.has("path")) {
                        path = jsonObject.getString("path");
                    }
                    // 上传成功
                    if (code == 1) {
                        sb.append(path);
                        sb.append(SEPARATOR);
                    }
                }
                if (sb.length() > 0) {
                    sb.deleteCharAt(sb.lastIndexOf(SEPARATOR));
                }
                return Observable.just(sb.toString());
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                if (listener != null) {
                    if (!TextUtils.isEmpty(uploadedStr)) {
                        listener.uploadComplete(uploadedStr + SEPARATOR + s);
                    } else {
                        listener.uploadComplete(s);
                    }
                }
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                if (listener != null) {
                    listener.uploadError(throwable.getMessage());
                }
            }
        });
    }

    /**
     * 上传签名图片
     *
     * @param taskId     任务id
     * @param type       步骤
     * @param uploadList 需要上传的本地图片集合
     * @param listener   上传结果监听器
     */
    public void uploadSignPicture(final long taskId, final int type, final ArrayList<ImageBean> uploadList, final UploadListener listener) {
        String sdCardPath = SDCardFileUtils.getSDCardPath();
        if (TextUtils.isEmpty(sdCardPath)) {
            ToastUtils.t(mApplication, "获取内存卡失败");
            return;
        }
        final String dir2SDCard = ConstUtils.uploadNeedPictureDir();
        Observable.defer(new Callable<ObservableSource<ArrayList<String>>>() {
            @Override
            public ObservableSource<ArrayList<String>> call() throws Exception {
                ArrayList<String> list = new ArrayList<>();
                int size = uploadList.size();
                for (int i = 0; i < size; i++) {
                    ImageBean bean = uploadList.get(i);
                    try {
                        File file = new File(bean.getImgPath());
                        if (!file.exists()) continue;
                        String timeStamp = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss", Locale.ENGLISH).format(new Date());
                        String targetFilePath = dir2SDCard + "/" + timeStamp + "_" + i + "_" + file.getName();
                        String resultStr = BitmapUtil.compressBitmap(bean.getImgPath(), targetFilePath, 500);
                        if (resultStr.equals(COMPRESS_SUCCESS)) {
                            list.add(targetFilePath);
                        }
                    } catch (Exception e) {
                    }
                }
                return Observable.just(list);
            }
        }).subscribeOn(Schedulers.io()).flatMap(new Function<ArrayList<String>, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(ArrayList<String> list) throws Exception {
                StringBuilder sb = new StringBuilder();
                for (String str : list) {
                    File file = new File(str);
                    // 文件不存在
                    if (!file.exists()) continue;
                    Response response = OkHttpUtils
                            .post()
                            .url(Constant.SIGN_UPLOAD_URL)
                            .addParams("taskId", taskId + "")
                            .addFile("file", file.getName(), file)
                            .build().execute();
                    String bodyStr = response.body().string();
                    JSONObject jsonObject = new JSONObject(bodyStr);
                    int code = 0;
                    String path = null;
                    if (jsonObject.has("code")) {
                        code = jsonObject.getInt("code");
                    }
                    if (jsonObject.has("path")) {
                        path = jsonObject.getString("path");
                    }
                    // 上传成功
                    if (code == 1) {
                        sb.append(path);
                        sb.append(SEPARATOR);
                    }
                }
                if (sb.length() > 0) {
                    sb.deleteCharAt(sb.lastIndexOf(SEPARATOR));
                }
                return Observable.just(sb.toString());
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                if (listener != null) {
                    listener.uploadComplete(s);
                }
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                if (listener != null) {
                    listener.uploadError(throwable.getMessage());
                }
            }
        });
    }
}
